package com.codedancer.campus.manager.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.codedancer.campus.common.exception.BusinessException;
import com.codedancer.campus.common.utils.UUIDGenerator;
import com.codedancer.campus.manager.service.IUpdateLogService;
import com.codedancer.campus.manager.service.bo.updateLog.UpdateLogAddOrUpdateBo;
import com.codedancer.campus.manager.service.bo.updateLog.UpdateLogPageSearchBo;
import com.codedancer.campus.manager.service.vo.updateLog.UpdateLogPageVo;
import com.codedancer.campus.mapper.UpdateLogMapper;
import com.codedancer.campus.po.UpdateLog;
import com.codedancer.campus.qo.updateLog.UpdateLogPageSearchQo;
import java.util.List;
import java.util.stream.Collectors;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Slf4j
@Transactional(rollbackFor = Exception.class)
public class UpdateLogServiceImpl implements IUpdateLogService {

    @Autowired
    private UpdateLogMapper updateLogMapper;

    /**
     * 添加更新日志
     *
     * @param updateLogAddOrUpdateBo
     */
    @Override
    public void add(UpdateLogAddOrUpdateBo updateLogAddOrUpdateBo) {
        // 判断该版本是否存在
        if (updateLogMapper.existsByColumn("version", updateLogAddOrUpdateBo.getVersion())) {
            throw new BusinessException("该版本号已存在，请重新填写");
        }
        if (CollUtil.isEmpty(updateLogAddOrUpdateBo.getContents())) {
            throw new BusinessException("请填写更新内容");
        }
        // 先将其他版本更新日志修改为未置顶
        updateLogMapper.updateNoTop();
        UpdateLog updateLog = UpdateLog.builder()
            .uuid(UUIDGenerator.getUUID())
            .version(updateLogAddOrUpdateBo.getVersion())
            .content(JSONUtil.toJsonStr(updateLogAddOrUpdateBo.getContents()))
            .build();
        updateLogMapper.insert(updateLog);
    }

    /**
     * 更新日志修改Ro
     *
     * @param updateLogAddOrUpdateBo
     */
    @Override
    public void update(UpdateLogAddOrUpdateBo updateLogAddOrUpdateBo) {
        UpdateLog updateLog = updateLogMapper.findById(updateLogAddOrUpdateBo.getUuid())
            .orElseThrow(() -> new BusinessException("更新日志不存在"));
        if (updateLog.getIsPush()) {
            throw new BusinessException("更新日志已推送，不能修改");
        }
        if (CollUtil.isEmpty(updateLogAddOrUpdateBo.getContents())) {
            throw new BusinessException("请填写更新内容");
        }
        if (!updateLogAddOrUpdateBo.getVersion().equals(updateLog.getVersion())) {
            // 修改版本
            if (updateLogMapper.existsByColumn("version", updateLogAddOrUpdateBo.getVersion())) {
                throw new BusinessException("该版本号已存在，请重新填写");
            }
        }
        updateLog.setVersion(updateLogAddOrUpdateBo.getVersion());
        updateLog.setContent(JSONUtil.toJsonStr(updateLogAddOrUpdateBo.getContents()));
        updateLogMapper.updateById(updateLog);
    }

    /**
     * 分页查询更新日志
     *
     * @param updateLogPageSearchBo
     * @return
     */
    @Override
    public IPage<UpdateLogPageVo> page(UpdateLogPageSearchBo updateLogPageSearchBo) {
        UpdateLogPageSearchQo updateLogPageSearchQo = BeanUtil.copyProperties(updateLogPageSearchBo,
            UpdateLogPageSearchQo.class);
        IPage<UpdateLog> updateLogIPage = updateLogMapper.page(
            new Page<UpdateLog>(updateLogPageSearchBo.getPage(), updateLogPageSearchBo.getSize()),
            updateLogPageSearchQo);
        List<UpdateLogPageVo> updateLogPageVos;
        IPage<UpdateLogPageVo> updateLogPageVoIPage = new Page<>();
        updateLogPageVos = updateLogIPage.getRecords().stream().map(updateLog -> {
            UpdateLogPageVo updateLogPageVo = BeanUtil.copyProperties(updateLog,
                UpdateLogPageVo.class);
            List<String> contents = JSONUtil.toList(updateLog.getContent(), String.class);
            updateLogPageVo.setContents(contents);
            return updateLogPageVo;
        }).collect(Collectors.toList());
        updateLogPageVoIPage.setRecords(updateLogPageVos);
        updateLogPageVoIPage.setTotal(updateLogIPage.getTotal());
        return updateLogPageVoIPage;
    }

    /**
     * 删除更新日志
     *
     * @param uuid
     */
    @Override
    public void delete(String uuid) {
        if (!updateLogMapper.existsByUuId(uuid)) {
            throw new BusinessException("更新日志不存在");
        }
        updateLogMapper.deleteById(uuid);
        // 获取最新创建的更新日志
        UpdateLog updateLog = updateLogMapper.selectLastest();
        if (ObjectUtil.isNotEmpty(updateLog)) {
            updateLog.setIsTop(true);
            updateLogMapper.updateById(updateLog);
        }
    }

    /**
     * 推送更新日志
     *
     * @param uuid
     */
    @Override
    public void push(String uuid) {
        UpdateLog updateLog = updateLogMapper.findById(uuid)
            .orElseThrow(() -> new BusinessException("更新日志不存在"));
        updateLog.setIsPush(true);
        updateLogMapper.updateById(updateLog);
    }
}
